﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using AMM.Model;

namespace AMM.DataAccess.Config {
    public class UserRepository : BaseRepository<User> {
        public User FetchUserByUserId(int userId) {
            using (var ctx = this.Context) {
                return ctx.Users.Include("UserRoles").FirstOrDefault(x => x.UserId == userId);
            }
        }

        public Dictionary<string, int> FetchUserAllMenuPermission(int userId) {
            using (var ctx = this.Context) {
                var query = from a in ctx.UserRoles
                            join b in ctx.RoleFunctions on a.RoleId equals b.RoleId
                            join c in ctx.Functions on b.FunctionId equals c.FunctionId
                            where a.UserId == userId
                            group new { UserRoles = a, RoleFunctions = b, Functions = c } by new { a.UserId, c.Code } into d
                            select new {
                                Code = d.Key.Code,
                                Powers = d.Max(x => x.RoleFunctions.Powers)
                            };

                return query.ToDictionary(x => x.Code, y => y.Powers);
            }
        }

        public List<User> FetchUserList() {
            using (var ctx = this.Context) {
                return ctx.Users.ToList();
            }
        }

        public List<User> FetchUserByRole(int roleId) {
            using (var ctx = this.Context) {
                var query = from a in ctx.UserRoles
                            join b in ctx.Users on a.UserId equals b.UserId
                            where a.RoleId == roleId
                            select b;

                return query.ToList();
            }
        }

        public override void Update(User t) {
            using (var ctx = this.Context) {
                using (DbContextTransaction trans = ctx.Database.BeginTransaction()) {
                    try {
                        ctx.UserRoles.Where(x => x.UserId == t.UserId).ToList().ForEach(x => {
                            ctx.UserRoles.Remove(x);
                        });
                        ctx.SaveChanges();
                        base.Update(t);
                        trans.Commit();
                    }
                    catch (Exception ex) {
                        trans.Rollback();
                        throw ex;
                    }
                }
            }
        }

        public void DeleteMultipleUser(params int[] userIds) {
            using (var ctx = this.Context) {
                using (DbContextTransaction trans = ctx.Database.BeginTransaction()) {
                    try {
                        ctx.UserRoles.Where(x => userIds.Contains(x.UserId)).ToList().ForEach(x => {
                            ctx.UserRoles.Remove(x);
                        });
                        ctx.Users.Where(x => userIds.Contains(x.UserId)).ToList().ForEach(x => {
                            ctx.Users.Remove(x);
                        });
                        ctx.SaveChanges();
                        trans.Commit();
                    }
                    catch (Exception ex) {
                        trans.Rollback();
                        throw ex;
                    }
                }
            }
        }

    }
}
